import React, {useRef, useEffect, useState, useImperativeHandle, forwardRef, useCallback, useMemo} from "react"
import {EChartsOption, SelectChangedEvent, VulnerabilityLevelPieProps} from "./VulnerabilityLevelPieType"
import * as echarts from "echarts"
import classNames from "classnames"
import styles from "./VulnerabilityLevelPie.module.scss"
import {useControllableValue, useMemoizedFn, useSize, useUpdateEffect} from "ahooks"
import { useTheme } from "@/hook/useTheme"
import { getCssVar } from "@/utils/tool"

const dataMapColor = {
    0: {
        selectColor: "rgba(211, 58, 48, 1)",
        color: "rgba(211, 58, 48, 0.3)"
    },
    1: {
        selectColor: "rgba(246, 84, 74, 1)",
        color: "rgba(246, 84, 74, 0.3)"
    },
    2: {
        selectColor: "rgba(255, 182, 96, 1)",
        color: "rgba(255, 182, 96, 0.3)"
    },
    3: {
        selectColor: "rgba(255, 213, 131, 1)",
        color: "rgba(255, 213, 131, 0.3)"
    },
    4: {
        selectColor: "rgba(86, 201, 145, 1)",
        color: "rgba(86, 201, 145, 0.3)"
    }
}

export const VulnerabilityLevelPie: React.FC<VulnerabilityLevelPieProps> = React.memo(
    forwardRef((props, ref) => {
        const {className = "", list} = props
        const {theme} = useTheme()
        const chartRef = useRef(null)
        const [selectList, setSelectList] = useControllableValue<string[]>(props, {
            defaultValue: [],
            valuePropName: "selectList",
            trigger: "setSelectList"
        })

        const getData = useMemoizedFn(() => {
            let seriousNumber = 0
            let highNumber = 0
            let middleNumber = 0
            let lowNumber = 0
            let infoNumber = 0
            const newData = Array(5).fill(null)
            list.forEach((ele) => {
                if (ele.Verbose.includes("严重") && ele.Total > 0) {
                    seriousNumber = ele.Total
                    newData[0] = {
                        name: ele.Verbose,
                        key: ele.Name,
                        value: seriousNumber,
                        selected: true,
                        itemStyle: {
                            color: dataMapColor[0].color
                        },
                        select: {
                            itemStyle: {
                                color: dataMapColor[0].selectColor
                            }
                        },
                        label:{
                            color: getCssVar('--Colors-Use-Neutral-Text-1-Title')
                        }
                    }
                }
                if (ele.Verbose.includes("高危") && ele.Total > 0) {
                    highNumber = ele.Total
                    newData[1] = {
                        name: ele.Verbose,
                        key: ele.Name,
                        value: highNumber,
                        selected: true,
                        itemStyle: {
                            color: dataMapColor[1].color
                        },
                        select: {
                            itemStyle: {
                                color: dataMapColor[1].selectColor
                            }
                        },
                        label:{
                            color: getCssVar('--Colors-Use-Neutral-Text-1-Title')
                        }
                    }
                }
                if (ele.Verbose.includes("中危") && ele.Total > 0) {
                    middleNumber = ele.Total
                    newData[2] = {
                        name: ele.Verbose,
                        key: ele.Name,
                        value: middleNumber,
                        selected: true,
                        itemStyle: {
                            color: dataMapColor[2].color
                        },
                        select: {
                            itemStyle: {
                                color: dataMapColor[2].selectColor
                            }
                        },
                        label:{
                            color: getCssVar('--Colors-Use-Neutral-Text-1-Title')
                        }
                    }
                }
                if (ele.Verbose.includes("低危") && ele.Total > 0) {
                    lowNumber = ele.Total
                    newData[3] = {
                        name: ele.Verbose,
                        key: ele.Name,
                        value: lowNumber,
                        selected: true,
                        itemStyle: {
                            color: dataMapColor[3].color
                        },
                        select: {
                            itemStyle: {
                                color: dataMapColor[3].selectColor
                            }
                        },
                        label:{
                            color: getCssVar('--Colors-Use-Neutral-Text-1-Title')
                        }
                    }
                }
                if (ele.Verbose.includes("信息") && ele.Total > 0) {
                    infoNumber = ele.Total
                    newData[4] = {
                        name: ele.Verbose,
                        key: ele.Name,
                        value: infoNumber,
                        selected: true,
                        itemStyle: {
                            color: dataMapColor[4].color
                        },
                        select: {
                            itemStyle: {
                                color: dataMapColor[4].selectColor
                            }
                        },
                        label:{
                            color: getCssVar('--Colors-Use-Neutral-Text-1-Title')
                        }
                    }
                }
            })
            return newData.filter((ele) => !!ele) // 过滤掉null
        })
        const optionRef = useRef<EChartsOption>({
            series: [
                {
                    type: "pie",
                    radius: [15, 95],
                    roseType: "radius",
                    itemStyle: {
                        borderRadius: 4
                    },
                    minAngle: 20,
                    data: [],
                    percentPrecision: 0,
                    label: {
                        fontSize: 12,
                        color: "#31343F",
                        formatter: "{b}\n{d}%",
                        lineHeight: 16,
                        overflow: "break"
                    },
                    selectedMode: "multiple",
                    selectedOffset: 0,
                    select: {
                        itemStyle: {}
                    },
                    emphasis: {
                        scale: true,
                        scaleSize: 5,
                        itemStyle: {
                            opacity: 0.9
                        }
                    },
                    labelLine: {
                        length: 5,
                        length2: 10
                    }
                }
            ]
        })
        const pieChart = useRef<echarts.ECharts>()
        const dataRef = useRef<any[]>([])
        useImperativeHandle(
            ref,
            () => ({
                onReset,
                onResize:()=>{
                    pieChart.current?.resize()
                }
            }),
            []
        )
        useEffect(() => {
            if (list && list.length > 0) {
                if (!pieChart.current) pieChart.current = echarts.init(chartRef.current)
                if (!!(optionRef.current.series && optionRef.current.series[0])) {
                    dataRef.current = getData()
                    if (optionRef.current.series[0].data.length === 0) {
                        optionRef.current.series[0].data = dataRef.current
                        pieChart.current.setOption(optionRef.current)
                    } else {
                        const newData = dataRef.current.map((ele) => {
                            if (selectList.length === 0) {
                                return ele
                            } else {
                                ele.selected = selectList.includes(ele.key)
                                return ele
                            }
                        })
                        optionRef.current.series[0].data = newData
                        pieChart.current.setOption(optionRef.current, true)
                    }
                }

                pieChart.current.on("selectchanged", onSelectChanged)
            }

            return () => {
                if (pieChart.current) {
                    pieChart.current.off("selectchanged", onSelectChanged)
                    pieChart.current.dispose()
                    pieChart.current = undefined
                }
            }
        }, [list,theme])
        useUpdateEffect(() => {
            /** 当最后一个选中状态被取消时，UI默认全选 */
            if (!(optionRef.current.series && optionRef.current.series[0])) return
            optionRef.current.series[0].data = dataRef.current.map((ele) => ({
                ...ele,
                selected:
                    selectList.length == 0
                        ? true
                        : selectList.includes(list.find((l) => l.Verbose === ele.name)?.Name || "")
            }))
            pieChart.current?.setOption(optionRef.current, true)
        }, [selectList, list])
        const onReset = useMemoizedFn(() => {
            if (!pieChart.current) return
            if (!!(optionRef.current.series && optionRef.current.series[0])) {
                const data = getData()
                dataRef.current = data
                optionRef.current.series[0].data = dataRef.current
            }
            pieChart.current.setOption(optionRef.current, true)
            setSelectList([])
        })
        /**数据选中状态发生变化时触发的事件 */
        const onSelectChanged = useMemoizedFn((value) => {
            const {fromAction, fromActionPayload} = value as any as SelectChangedEvent
            //不额外处理全选
            if (fromAction === "toggleSelect") {
                return
            }
            const {dataIndexInside} = fromActionPayload
            const data = dataRef.current
            
            const selectKey = data[dataIndexInside].key
            let newSelect = [...selectList]
            if (selectList.length === 0 && fromAction === "unselect" && pieChart.current) {
                newSelect.push(selectKey)
            } else {
                switch (fromAction) {
                    case "select":
                        if (newSelect.length > 0 && newSelect.includes(selectKey)) return
                        newSelect.push(selectKey)
                        break
                    case "unselect":
                        newSelect = selectList.filter((ele) => ele != selectKey)
                        break
                    default:
                        break
                }
            }
            setSelectList(newSelect)
        })
        return <div className={classNames(styles["vulnerability-level-pie"], className)} ref={chartRef}></div>
    })
)
